package automaticTagging;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLClassLoader;

import dbManager.Manager;

/**
 * This class connecting to the spy program and calling functions that update the DB
 *  according the message that was sent from the spy
 */
public class AutomaticTagging implements Runnable
{
	boolean mainIsActive=true;
	String path=null;
	ServerSocket serverSocket=null;
	Manager updateDB = Manager.getInstance();
	Socket clientSocket=null;
	
	/**
	 * @return true if the parameter 'mainIsActive' is true
	 * 			else - return false.
	 */
	public boolean isMainIsActive() 
	{
		return mainIsActive;
	}

	/**
	 * @param mainIsActive - is updated here
	 */
	public void setMainIsActive(boolean mainIsActive) 
	{
		this.mainIsActive = mainIsActive;
	}

	/**
	 * This function connecting to the spy project by socket protocol
	 * @throws IOException
	 */
	public void connectToSpyProgram() throws IOException
	{
		/*'path', 'name', 'sign' are updated according to the socket in the spy program*/
		String path = null;
		String name = null;
		String sign = null;
		BufferedReader in = null;
		PrintWriter out = null;
		try 
		{ 
			serverSocket = new ServerSocket(4444);
		}
		catch (IOException e) 
		{ 
			System.err.println("Cannot listen on port 4444");
			System.exit(-1);
		}
		while (mainIsActive)
		{
			try 
			{ 
				clientSocket=serverSocket.accept();
				in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
				out = new PrintWriter(clientSocket.getOutputStream(),true);
				
				/*these 3 parameters are updated according to the spy program*/
				sign = in.readLine();
				path = in.readLine();
				name = in.readLine();
			}
			catch (IOException e){}

			if(sign != null)
			{
				if(path != null)
				{
					if(name != null)
					{
						//the case a directory was deleted.
						if(sign.equals("delete - dir"))
						{
							//deleting from DB 'tags'
							updateDB.deleteRemovedFileTags();
						}
						else
						{
							/*this code is for loading dynamically the class which responsible 
							 * to tag the file*/
							File f = new File("C:/userPlugIn");
							String labels[];
							try 
							{
								// Convert File to a URL
								URL url = f.toURL();
								URL[] urls = new URL[]{url};

								// Create a new class loader with the directory
								ClassLoader cl = new URLClassLoader(urls);
								Class cls =  cl.loadClass("automaticTagging.MyFileLabeler");
								FileLabeler fl= (FileLabeler) cls.newInstance();
								File file = new File(path);
								labels = fl.label(file);
								
								
								//now we will update the data base with the new tags
								if(sign.equals("create"))
								{
									//enter the new tags to DB 'tags'
									updateDB.updateDB(labels, name, path, true);	
								}
								else
								{
									if(sign.equals("delete"))
									{
										//delete from DB the tags of this file
										updateDB.updateDB(labels, name, path, false);
									}
								}	    
							} 
							catch (MalformedURLException e){} 
							catch (ClassNotFoundException e) {} 
							catch (InstantiationException e) {} 
							catch (IllegalAccessException e) {}
						}
					}
				}
			}
			if (clientSocket != null)
			{
				clientSocket.close();
				clientSocket = null;
			}
		}
	}

	/**
	 * Running the function connectToSpyProgram() in new thread
	 * */
	public void run() 
	{
		try 
		{
			connectToSpyProgram();
		}
		catch (IOException e) {}
		
	}
	
	/**
	 * This function responsible to close the connecting 
	 * 					between this class to the spy program
	 * */
	public void close() throws IOException
	{
		if (clientSocket != null)
		{
			clientSocket.close();
			clientSocket = null;
		}
		if (serverSocket != null) serverSocket.close();
		mainIsActive = false;
	}
}
